package com.itheima.tlias.execption;

import com.itheima.tlias.common.result.Result;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.StringJoiner;

/**
 * 因为我们无法用try-catch捕获进入controller之前的异常
 * ，但是可以使用aop对controller进行调用之前的增强
 * 因此@ControllerAdvice相当于环绕通知controller
 */
/**
 * 全局异常处理器
 * 使用AOP对Controller方法调用前进行增强，处理进入Controller之前的异常
 */
@RestControllerAdvice
public class GobalExeceptionHandler {

    /**
     * 处理ArithmeticException异常
     * 当出现算术异常时，返回内部服务器错误状态和错误信息
     *
     * @return 包含错误信息的结果对象
     */
    @ExceptionHandler(ArithmeticException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Result handleArithmeticException(){
        return Result.error("发生1/0算数异常");
    }

    /**
     * 处理MethodArgumentNotValidException异常
     * 当请求参数校验失败时，返回坏请求状态和校验错误信息
     *
     * @param exception 参数校验异常对象
     * @return 包含校验错误信息的结果对象
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Result handleMethodArgumentNotValidException(MethodArgumentNotValidException exception){
        // 获取第一个校验错误的信息
        String defaultMessage = exception.getFieldError().getDefaultMessage();
        // 获取被拒绝的值
        Object rejectedValue = exception.getFieldError().getRejectedValue();
        // 获取全部校验信息
        BindingResult bindingResult = exception.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        // 使用StringJoiner拼接所有校验错误信息
        StringJoiner stringJoiner = new StringJoiner(",", "[", "]");
        for (FieldError fieldError : fieldErrors) {
            stringJoiner.add(fieldError.getDefaultMessage());
        }
        // 返回所有校验错误信息
        return Result.error(stringJoiner.toString());
    }

}
